/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.testis.gui.mvc.view.labels;

import org.testis.orm.labelhandler.LabelRefined;
import org.testis.utils.tree.DefaultMutableLabelNode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;

import org.testis.utils.tree.TristateLabelTreeNode;
import org.testis.utils.tree.TristateState;

/**
 *
 * @author selcuk
 */
public class LabelJTreeWithTriStateCheckbox extends JTree {

    public LabelJTreeWithTriStateCheckbox() {
        super();
        initLabelTree();
        refreshLabelTree(loadLabelTreeModel());
    }

    private void initLabelTree() {
        getSelectionModel().setSelectionMode(
                TreeSelectionModel.SINGLE_TREE_SELECTION);
        setCellRenderer(new TristateLabelTreeNodeRenderer());
        setCellEditor(new TristateLabelTreeNodeEditor(this));
        setEditable(true);
        setExpandsSelectedPaths(false);
        setRootVisible(false);
    }

    private void refreshLabelTree(DefaultTreeModel model) {
        setModel(model);
        updateUI();
        expand();
    }

    private void expand() {
        for (int i = 0; i < getRowCount(); i++) {
            expandRow(i);
        }
    }

    private DefaultTreeModel loadLabelTreeModel() {
        ILabelTreeLoader treeLoader = new TristateLabelTreeLoader();
        DefaultMutableLabelNode root = treeLoader.loadTree();
        return new DefaultTreeModel(root);
    }

    public List<DefaultMutableLabelNode> getSelectedNodes() {
        List<DefaultMutableLabelNode> result = new ArrayList<DefaultMutableLabelNode>();
        javax.swing.tree.TreeModel model = getModel();
        if (model != null) {
            Object root = model.getRoot();
            walkForSelectedNodes(model, root, result);
        }
        return result;
    }

    private void walkForSelectedNodes(javax.swing.tree.TreeModel model, Object o, List<DefaultMutableLabelNode> selectedNodes) {
        DefaultMutableLabelNode node = (DefaultMutableLabelNode) o;
        if (node != null) {
            TristateLabelTreeNode tristateLabel = (TristateLabelTreeNode) node.getUserObject();
            if (tristateLabel != null) {
                TristateState tristate = tristateLabel.getState();
                if (tristate == TristateState.SELECTED || tristate == TristateState.INDETERMINATE) {
                    selectedNodes.add(node);
                }
            }
            if (!model.isLeaf(o)) {
                int cc = model.getChildCount(o);
                for (int i = 0; i
                        < cc; i++) {
                    Object child = model.getChild(o, i);
                    walkForSelectedNodes(model, child, selectedNodes);
                }
            }
        }
    }

    public String getLabelSelectionStr() {
        StringBuilder sb = new StringBuilder();
        List<DefaultMutableLabelNode> selectedNodes = getSelectedNodes();
        for (Iterator<DefaultMutableLabelNode> it = selectedNodes.iterator(); it.hasNext();) {
            DefaultMutableLabelNode defaultMutableLabelNode = it.next();
            LabelRefined lblRefined = defaultMutableLabelNode.getLabel();
            TristateLabelTreeNode tristateNode = (TristateLabelTreeNode) defaultMutableLabelNode.getUserObject();
            if (tristateNode.getState() == TristateState.SELECTED) {
                sb.append(" " + lblRefined.getName() + " AND");
            } else if (tristateNode.getState() == TristateState.INDETERMINATE) {
                sb.append(" !" + lblRefined.getName() + " AND");
            }
        }
        String result = sb.toString().trim();
        if (result.endsWith("AND")) {
            result = result.substring(0, result.length() - 3).trim();
        }
        return result;
    }

    public void deselectNodes() {
        List<DefaultMutableLabelNode> selectedNodes = getSelectedNodes();
        for (Iterator<DefaultMutableLabelNode> it = selectedNodes.iterator(); it.hasNext();) {
            DefaultMutableLabelNode node = it.next();
            TristateLabelTreeNode tristateNode = (TristateLabelTreeNode) node.getUserObject();
            tristateNode.setState(TristateState.DESELECTED);
        }
        updateUI();
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("Demo");
                frame.getContentPane().add(new LabelJTreeWithTriStateCheckbox());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }/**/

}
